package com.zkyc.framework.file.util;

import com.zkyc.framework.common.constant.Constant;
import io.minio.*;
import io.minio.errors.*;
import io.minio.http.Method;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;


public class MinioUtils {

    /**
     * 文件url前半段
     *
     * @param bucket 桶
     * @return 前半段
     */
    public static String getObjectPrefixUrl(String bucket) {
        return String.format("%s/", bucket);
    }



    /**
     * 上传本地文件
     *
     * @param bucket    桶
     * @param objectKey 文件key
     * @param filePath  文件路径
     * @return 文件url
     */
    public static String uploadFile(String bucket, String objectKey, String filePath) throws Exception {
        MinioClientSingleton.getMinioClient().uploadObject(UploadObjectArgs.builder().bucket(bucket).object(objectKey).filename(filePath).contentType("image/png").build());
        return getObjectPrefixUrl(bucket) + objectKey;
    }

    /**
     * 流式上传文件
     *
     * @param bucket      桶
     * @param objectKey   文件key
     * @return 文件url
     */
    public static String uploadInputStream(String bucket, String objectKey, MultipartFile file) throws Exception {
        final InputStream inputStream = file.getInputStream();
        uploadByInputStream(bucket, objectKey, inputStream);
        return getObjectPrefixUrl(bucket) + objectKey;
    }

    public static void uploadByInputStream(String bucket, String objectKey, InputStream inputStream) throws ErrorResponseException, InsufficientDataException, InternalException, InvalidKeyException, InvalidResponseException, IOException, NoSuchAlgorithmException, ServerException, XmlParserException {
        MinioClient client = MinioClientSingleton.getMinioClient();
        boolean exists = client.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());
        if (!exists) {
            client.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());
        }
        client.putObject(PutObjectArgs.builder().bucket(bucket).object(objectKey).stream(inputStream, inputStream.available(), -1).contentType("image/png").build());
        inputStream.close();
    }

    /**
     * 流式上传文件
     *
     * @param bucket      桶
     * @param objectKey   文件key
     * @return 文件url
     */
    public static String uploadInputStream(String bucket, String objectKey, InputStream inputStream) throws Exception {
        uploadByInputStream(bucket, objectKey, inputStream);
        return getObjectPrefixUrl(bucket) + objectKey;
    }

    /**
     * 获取文件流
     *
     * @param bucket    桶
     * @param objectKey 文件key
     * @return 文件流
     */
    public static InputStream getInputStream(String bucket, String objectKey) throws Exception {
        return MinioClientSingleton.getMinioClient().getObject(GetObjectArgs.builder().bucket(bucket).object(objectKey).build());
    }

    /**
     * 获取文件流
     *
     * @param bucket    桶
     * @param objectKey 文件key
     * @return 文件流
     */
    public static void download(String bucket, String objectKey, String filePath,String originalFileName) throws Exception {
        if (filePath != null){
            makeFilePath(filePath);
        }else{
            filePath = Constant.DEFAULT_FILE_PATH_WINDOWS;
        }
        MinioClientSingleton.getMinioClient().downloadObject(DownloadObjectArgs.builder().bucket(bucket).object(objectKey).filename(filePath + "/" + (originalFileName == null ? objectKey : originalFileName)).build());
    }

    /**
     * 文件复制
     *
     * @param sourceBucket    源桶
     * @param sourceObjectKey 源文件key
     * @param bucket          桶
     * @param objectKey       文件key
     * @return 新文件url
     */
    public static String copyFile(String sourceBucket, String sourceObjectKey, String bucket, String objectKey) throws Exception {
        CopySource source = CopySource.builder().bucket(sourceBucket).object(sourceObjectKey).build();
        MinioClientSingleton.getMinioClient().copyObject(CopyObjectArgs.builder().bucket(bucket).object(objectKey).source(source).build());
        return getObjectPrefixUrl(bucket) + objectKey;
    }

    /**
     * 返回文件 URL
     *
     * @param fileName 文件名
     * @return
     */
    public static String getPresignedObjectUrl(String fileName, String bucket) throws Exception {
        String url = MinioClientSingleton.getMinioClient().getPresignedObjectUrl(
                GetPresignedObjectUrlArgs.builder()
                        .method(Method.GET)
                        .bucket(bucket)
                        .object(fileName)
                        .build());
        return url;
    }

    /**
     * 删除文件
     *
     * @param bucket    桶
     * @param objectKey 文件key
     */
    public static void deleteFile(String bucket, String objectKey) throws Exception {
        MinioClientSingleton.getMinioClient().removeObject(RemoveObjectArgs.builder().bucket(bucket).object(objectKey).build());
    }

    public static void main(String[] args) {
        String bucket = "dcim";
        String objectKey = "demo/123.png";
        //String objectKey = "group1/M00/00/19/wKgBDllU7pyAbPD_AAVuXfDy4-A049.png";
        try {
            // 创建桶
            //makeBucket(bucket);
            // 设置桶读写权限
            //setBucketPolicy(bucket, "read-write");
            // 上传本地文件
            String url1 = uploadFile(bucket, objectKey, "/tmp/123.png");
            // 输出  http://127.0.0.1:9000/demo/123.png
            System.out.println(url1);
            // 上传文件流
            //      String url2 = uploadInputStream(bucket, objectKey, new File("/tmp/123.png"));
            // 输出  http://127.0.0.1:9000/demo/123.png
          //  System.out.println(url2);
            // 下载文件
            InputStream inputStream = getInputStream(bucket, objectKey);
            // 文件复制
            String url3 = copyFile(bucket, objectKey, "dcim", "test/abc.png");
            // 输出  http://127.0.0.1:9000/test/abc.png
            System.out.println(url3);
            // 删除文件
            deleteFile("dcim", "test/abc.png");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //创建文件夹,返回绝对路径
    public static void makeFilePath(String filePath) {
        File fileAbsolutePath = new File(filePath);
        if (!fileAbsolutePath.exists()) {
            fileAbsolutePath.mkdirs();
        } else {
            try {
                fileAbsolutePath.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    public static Boolean deleteFile(File file) {
        //判断文件不为null或文件目录存在
        if (file == null || !file.exists()) {
            System.out.println("文件删除失败,请检查文件是否存在以及文件路径是否正确");
            return false;
        }
        //获取目录下子文件
        File[] files = file.listFiles();
        //遍历该目录下的文件对象
        for (File f : files) {
            //判断子目录是否存在子目录,如果是文件则删除
            if (f.isDirectory()) {
                //递归删除目录下的文件
                deleteFile(f);
            } else {
                //文件删除
                f.delete();
                //打印文件名
                System.out.println("文件名：" + f.getName());
            }
        }
        //文件夹删除
        file.delete();
        System.out.println("目录名：" + file.getName());
        return true;
    }
}